package uk.co.wroedevelopments.semanticworkbench.query;

import java.util.ArrayList;
import java.util.List;

import org.neo4j.api.core.Direction;
import org.neo4j.api.core.Relationship;
import org.xtext.example.semQryDsl.Node;
import org.xtext.example.semQryDsl.Param;
import org.xtext.example.semQryDsl.Pattern;

import uk.co.wroedevelopments.semanticworkbench.store.Connection;
import uk.co.wroedevelopments.semanticworkbench.store.DynamicRelationshipType;
import uk.co.wroedevelopments.semanticworkbench.store.SemanticRelationshipType;

public class NeoQueryAction implements QueryAction {

	private Pattern pattern;

	public NeoQueryAction(Pattern p) {
		this.pattern = p;

	}

	public ResultList perform() {
		// TODO
		// should the result of this be a subgraph or just the bound variable
		// sets
		// perhaps the sets first
		/*
		 * set up a traverser with depth 1 a certain relationship type, a
		 * direction depending which is the concrete value and set the start
		 * node as the concrete value
		 */

		// TODO need to set up some test fixtures with some instance data in
		ResultList resultList = new ResultList();
		// which one to start from
		// both start and finish known
		
		if (!QueryUtils.isRelationshipInstance(pattern.getPredicate())) {
			throw new RuntimeException("Predicate must point to a specific relationship type at the moment");
		}

		if (QueryUtils.hasBothConcreteInstance(pattern)) {
			performSubjectObjectQuery(resultList);
			return resultList;
		} else {
			if (QueryUtils.isInstance(pattern.getSubject())) {
				performSubjectQuery(resultList);
				return resultList;
			} else {
				if (QueryUtils.isInstance(pattern.getObject())) {
					peformObjectQuery(resultList);
					return resultList;
				}
			}
		}

		throw new RuntimeException("Query not yet implemented");

	}

	private void peformObjectQuery(ResultList resultList) {
		// TODO Auto-generated method stub

	}

	private void performSubjectQuery(ResultList resultList) {
		Node subj = pattern.getSubject();
		org.neo4j.api.core.Node start = Connection.getIndexService()
				.getSingleNode(QueryUtils.NODE_ID_FIELD, subj.getName());
		DynamicRelationshipType rel = new DynamicRelationshipType(pattern
				.getPredicate().getName());
		Iterable<Relationship> rels = start.getRelationships(rel,
				Direction.OUTGOING);
		for (Relationship r : rels) {
			// do something different here to get all objects and put in a
			// binding
			ResultGraph rg = new ResultGraph(r);
			String param = pattern.getObject().getName();
			rg.setParameterBindingToObject(param);
			
			resultList.add(rg);
			resultList.addBinding(param, r.getEndNode());
;		}

	}

	private void performSubjectObjectQuery(ResultList resultList) {
		Node subj = pattern.getSubject();
		org.neo4j.api.core.Node start = Connection.getIndexService()
				.getSingleNode(QueryUtils.NODE_ID_FIELD, subj.getName());
		DynamicRelationshipType rel = new DynamicRelationshipType(pattern
				.getPredicate().getName());
		Iterable<Relationship> rels = start.getRelationships(rel,
				Direction.OUTGOING);
		for (Relationship r : rels) {
			Object id = r.getEndNode().getProperty(QueryUtils.NODE_ID_FIELD);
			if (id.equals(pattern.getObject().getName())) {

				resultList.add(new ResultGraph(r));
			}
		}
		System.out.println("result size =" + resultList.size());

	};

}
